home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
NOVA - For the NeXT Workstation
/
NOVA - For the NeXT Workstation.iso
/
Apps
/
Utilities
/
Other
/
Briefcase
/
Help.m
< prev
next >
Wrap
Text File
|
1992-12-26
|
7KB
|
224 lines
/*
* Help.m, a help object to manage and display RTF help files.
* The help object owns its own nib section "Help.nib" which has a
* Help panel - with an NXBrowser to display the help topics, and
* a scrolling text view to display the help files. The help files are
* all stored as RTF text files in a directory called Help within the
* app wrapper. At init time, the Help object loads the browser with
* names of all the files found in the Help directory. When a name is
* chosen from the browser, the help object opens a stream on that file
* and read the rich text into the text object. The help object also
* responds to request for context-sensitive help, by trying to find an
* appropriate help file for the view that was moused down in.
* This object is a useful addition to any program, because all users
* appreciate help!
*
* Author: Julie Zelenski, NeXT Developer Support
* You may freely copy, distribute and reuse the code in this example.
* NeXT disclaims any warranty of any kind, expressed or implied, as to
* its fitness for any particular use.
*/
/* Modified starting 9/21/91 by Subrata K. Sircar */
/* Mostly I've removed functionality. */
#import "Help.h"
#import <appkit/appkit.h>
#import <sys/dir.h> //for getdirentries()
#define GENERAL_HELP_FILE LocalString("General Help.rtf")
@implementation Help:Object
- init
{
LocalHelp(helpDirectory,LocalString("Help"));
sprintf(noHelpFile,"%s/%s",helpDirectory,GENERAL_HELP_FILE);
return self;
}
- setHelpBrowser:anObject;
/* Sets the helpBrowser outlet, and calls on the browser to load up.
*/
{
helpBrowser = anObject;
[helpBrowser setDelegate:self];
[helpBrowser loadColumnZero];
return self;
}
/* TARGET/ACTION METHODS */
- generalHelp:sender;
/* This is the target/action method for the "Help" menu item. This method
* will show the "general help" file.
*/
{
[self showHelpFile:GENERAL_HELP_FILE];
return self;
}
- browserHit:sender
/* This is the target/action method from the help topics browser. When
* a help topic is selected, this method will show the help file for that
* topic.
*/
{
[self showHelpFile:[[[sender matrixInColumn:0] selectedCell] stringValue]];
return self;
}
- print:sender;
/* This method is called by the Print menu cell in the main menu. It will
* print the current help file.
*/
{
[[helpScrollView docView] printPSCode:sender];
return self;
}
- showHelpFile:(const char *)filename;
/* Tries to open a stream for the specified file in the Help
* directory so the text object can readRichText. Also selects the
* filename in the browser of help topics. If the filename doesn't exist,
* it will select and display the "no help" file. It also brings the
* help panel to the front.
*/
{
NXStream *stream;
char helpFile[MAXPATHLEN+1];
static NXPoint origin = {0.0,0.0};
if (![self browser:helpBrowser selectCell:filename inColumn:0])
[self browser:helpBrowser selectCell:GENERAL_HELP_FILE inColumn:0];
sprintf(helpFile,"%s/%s",helpDirectory,filename);
if ((stream = NXMapFile(helpFile,NX_READONLY)) == NULL)
stream = NXMapFile(noHelpFile,NX_READONLY);
if (stream != NULL) {
[helpPanel disableFlushWindow];
[[helpScrollView docView] readRichText:stream];
[[helpScrollView docView] scrollPoint:&origin];
[[helpPanel reenableFlushWindow] flushWindow];
NXCloseMemory(stream,NX_FREEBUFFER);
}
[helpPanel orderFront:self];
return self;
}
static BOOL isOk(const char *s)
/* checks to make sure the filename is not NULL and to verify that it is
* not a "dot"--hidden file.
*/
{
return (!s[0] || s[0] == '.') ? NO : YES;
}
static int caseInsensitiveCompare(void *arg1, void *arg2)
/* Compares the two arguments without regard for case using strcasecmp().
*/
{
char *string1, *string2;
string1 = *((char **)arg1);
string2 = *((char **)arg2);
return strcasecmp(string1,string2);
}
static char **fileList;
- (int)browser:sender fillMatrix:matrix inColumn:(int)column
/* This delegate method goes out to the help directory and gets a list
* of all the files in that directory. It creates a list of file names
* for the static variable fileList, and will load the filenames into the
* browser on demand (lazy loading).
*/
{
long basep;
char *buf;
struct direct *dp;
char **list = NULL;
int cc, fd, fileCount = 0;
char dirbuf[8192];
if ((fd = open(helpDirectory, O_RDONLY, 0644)) > 0) {
cc = getdirentries(fd, (buf = dirbuf), 8192, &basep);
while (cc) {
dp = (struct direct *)buf;
if (isOk(dp->d_name)) {
list = addFile(dp->d_name, list, fileCount++, MyZone);
}
buf += dp->d_reclen;
if (buf >= dirbuf + cc) {
cc = getdirentries(fd, (buf = dirbuf), 8192, &basep);
}
}
close(fd);
if (list) qsort(list,fileCount,sizeof(char *),caseInsensitiveCompare);
}
freeList(fileList);
fileList = list;
return fileCount;
}
- browser:sender loadCell:cell atRow:(int)row inColumn:(int)column
/* This delegate method loads the cell for a given row. The stringValue
* for that row comes from the fileList.
*/
{
if (fileList) {
id originalFont = [cell font];
id useFont = [Font newFont:LocalHelpFont() size:[originalFont pointSize]];
if (useFont) {
[cell setFont:useFont];
[originalFont free];
}
[cell setStringValueNoCopy:fileList[row]];
[cell setLeaf:YES];
}
return self;
}
- (BOOL)browser:sender selectCell:(const char *)title inColumn:(int)column
/* This delegate method selects the cell with the given title. If it finds
* a cell with that title, it verifies that it has a file entry in the
* fileList, forces the loading of the cell, selects it (highlights) and
* scrolls the browser so the cell is visible. It returns a boolean value
* which indicates whether the cell was found.
*/
{
int row;
id matrix;
if (title) {
matrix = [sender matrixInColumn:column];
if (!fileList) return NO;
for (row = [matrix cellCount]-1; row >= 0; row--) {
if (fileList[row] && !strcmp(title, fileList[row])) {
[sender getLoadedCellAtRow:row inColumn:column];
[matrix selectCellAt:row :0];
[matrix scrollCellToVisible:row :0];
return YES;
}
}
}
return NO;
}
/* WINDOW DELEGATE METHODS */
- windowWillResize:sender toSize:(NXSize *)frameSize;
/* This method constrains the Help Panel to a reasonable minimum size
* when the user resizes the panel.
*/
{
frameSize->width = MAX(frameSize->width,400.0);
frameSize->height = MAX(frameSize->height,350.0);
return self;
}
@end